Skip to content

Create blocks to integrate Sessionize schedules and speakers#1081

Merged
cjyabraham merged 22 commits intomainfrom
sessionize
Apr 20, 2026
Merged

Create blocks to integrate Sessionize schedules and speakers#1081
cjyabraham merged 22 commits intomainfrom
sessionize

Conversation

@cjyabraham
Copy link
Copy Markdown
Collaborator

@cjyabraham cjyabraham commented Apr 15, 2026

Signed-off-by: Chris Abraham <cjyabraham@gmail.com>
Copilot AI review requested due to automatic review settings April 15, 2026 15:42
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aims to introduce a new WordPress block plugin under sessionize-schedule and wire it into the theme’s plugin install workflow.

Changes:

  • Added an install-sessionize-schedule npm script in the lfevents theme.
  • Added a new plugin directory web/wp-content/plugins/sessionize-schedule/ containing a block implementation and built assets.
  • Updated repo .gitignore to include the new plugin directory while ignoring its node_modules.

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
web/wp-content/themes/lfevents/package.json Adds an npm install script for the new plugin.
web/wp-content/plugins/sessionize-schedule/custom-iframe.php Registers a block (currently duplicates the existing Custom iFrame plugin).
web/wp-content/plugins/sessionize-schedule/block.json Block metadata (currently uses the existing lf/custom-iframe name).
web/wp-content/plugins/sessionize-schedule/build/index.js Built editor script (appears to be for Custom iFrame, not Sessionize).
web/wp-content/plugins/sessionize-schedule/build/index.css Editor CSS for the block.
web/wp-content/plugins/sessionize-schedule/build/style-index.css Declared front-end style file, but currently empty.
web/wp-content/plugins/sessionize-schedule/build/index.asset.php WP script dependency/version manifest for the build.
web/wp-content/plugins/sessionize-schedule/.gitignore Plugin-local ignores (node_modules, logs, etc.).
web/wp-content/plugins/sessionize-schedule/.editorconfig Plugin-local editor configuration.
.gitignore Ensures the new plugin directory is committed but its node_modules is ignored.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread web/wp-content/themes/lfevents/package.json Outdated
Comment thread web/wp-content/plugins/sessionize-schedule/block.json Outdated
Comment thread web/wp-content/themes/lfevents/package.json Outdated
Comment thread web/wp-content/plugins/sessionize-schedule/custom-iframe.php Outdated
Comment thread web/wp-content/plugins/sessionize-schedule/custom-iframe.php Outdated
Comment thread web/wp-content/plugins/sessionize-schedule/custom-iframe.php Outdated
Comment thread web/wp-content/plugins/sessionize-schedule/build/style-index.css Outdated
Comment thread web/wp-content/plugins/sessionize-schedule/build/index.js Outdated
@cjyabraham cjyabraham marked this pull request as draft April 15, 2026 15:52
Signed-off-by: Chris Abraham <cjyabraham@gmail.com>
Signed-off-by: Chris Abraham <cjyabraham@gmail.com>
Signed-off-by: Chris Abraham <cjyabraham@gmail.com>
Signed-off-by: Chris Abraham <cjyabraham@gmail.com>
Signed-off-by: Chris Abraham <cjyabraham@gmail.com>
Signed-off-by: Chris Abraham <cjyabraham@gmail.com>
Signed-off-by: Chris Abraham <cjyabraham@gmail.com>
Signed-off-by: Chris Abraham <cjyabraham@gmail.com>
Signed-off-by: Chris Abraham <cjyabraham@gmail.com>
Signed-off-by: Chris Abraham <cjyabraham@gmail.com>
Signed-off-by: Chris Abraham <cjyabraham@gmail.com>
Copilot AI review requested due to automatic review settings April 18, 2026 20:09

function getSessionAbstract_( session ) {
const raw = session?.description ?? session?.Description ?? session?.abstract ?? session?.Abstract ?? '';
return String( raw || '' ).replace( /<[^>]*>/g, '' ).trim();

function getBio_( speaker ) {
const b = speaker?.bio ?? speaker?.Bio ?? '';
return String( b || '' ).replace( /<[^>]*>/g, '' ).trim();
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 28 out of 31 changed files in this pull request and generated 6 comments.

Comments suppressed due to low confidence (1)

web/wp-content/themes/lfevents/package.json:43

  • The install-plugins aggregate script doesn't include the new Sessionize install script, so running npm run install-plugins will skip this plugin. Add the Sessionize install task to install-plugins (and likewise to build-plugins if you want it built with the rest).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

<div class="sz-modal__avatar" data-role="szModalAvatar"></div>

<div class="sz-modal__meta">
<h2 class="sz-modal__name" data-role="szModalTitle"></h2>
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aria-labelledby="szModalTitle" references an element id that isn't present in the markup (the <h2> only has data-role). This breaks screen reader labeling for the dialog. Add id="szModalTitle" to the title element (or update aria-labelledby to match the actual id).

Suggested change
<h2 class="sz-modal__name" data-role="szModalTitle"></h2>
<h2 class="sz-modal__name" id="szModalTitle" data-role="szModalTitle"></h2>

Copilot uses AI. Check for mistakes.
Comment on lines +88 to +91
<div
class="sched-wrapper sched"
data-sched-config="<?php echo esc_attr( wp_json_encode( $sched_config ) ); ?>"
<?php echo get_block_wrapper_attributes(); ?>
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This wrapper renders both a literal class="sched-wrapper sched" attribute and get_block_wrapper_attributes(), which will also output its own class attribute. Duplicate class attributes produce invalid HTML and can break block classes. Prefer using get_block_wrapper_attributes([ 'class' => 'sched-wrapper sched' ]) and remove the hard-coded class attribute.

Suggested change
<div
class="sched-wrapper sched"
data-sched-config="<?php echo esc_attr( wp_json_encode( $sched_config ) ); ?>"
<?php echo get_block_wrapper_attributes(); ?>
<div
data-sched-config="<?php echo esc_attr( wp_json_encode( $sched_config ) ); ?>"
<?php echo get_block_wrapper_attributes( array( 'class' => 'sched-wrapper sched' ) ); ?>

Copilot uses AI. Check for mistakes.
Comment on lines +736 to +742
const a = document.createElement( 'a' );
a.className = 'sz-modal__link';
a.href = String( link.url || '' ).trim();
a.target = '_blank';
a.rel = 'noopener';
a.setAttribute( 'aria-label', label );
a.title = label;
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Speaker social links set a.href directly from Sessionize data without validating the URL scheme. A javascript: (or other non-http/https) URL from upstream data would become an XSS vector. Before assigning href, validate/normalize to allow only http:/https: (and optionally mailto:) and skip/omit links that don't pass.

Copilot uses AI. Check for mistakes.
Comment on lines +1106 to +1114
document.addEventListener( 'keydown', ( e ) => {
if ( modal.getAttribute( 'aria-hidden' ) === 'true' ) {
return;
}
if ( e.key === 'Escape' ) {
e.preventDefault();
closeModal_();
}
} );
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wireModalControls_ attaches a document-level keydown listener for Escape inside initSpeakerGrid. If multiple Sessionize Speakers blocks appear on a page, this will register multiple global listeners. Consider registering the handler once (e.g., per-modal, or via a shared singleton) to avoid duplicated listeners and make teardown easier.

Copilot uses AI. Check for mistakes.
Comment on lines 32 to 33
"install-sessionize-schedule": "npm install --prefix ../../plugins/sessionize-schedule/",
"install-icon-list": "npm install --prefix ../../plugins/icon-list/",
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

install-sessionize-schedule points to ../../plugins/sessionize-schedule/, but the plugin added in this PR is web/wp-content/plugins/sessionize-blocks/ (and there is no sessionize-schedule directory). Update the script name/path to install the correct plugin directory.

Copilot uses AI. Check for mistakes.
Comment on lines +50 to +52
class="sz-speakers-wrap"
data-speaker-config="<?php echo esc_attr( wp_json_encode( $speaker_config ) ); ?>"
<?php echo get_block_wrapper_attributes(); ?>
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This wrapper renders both a literal class="sz-speakers-wrap" attribute and get_block_wrapper_attributes(), which will also output its own class attribute. Duplicate class attributes produce invalid HTML and can break block classes. Prefer using get_block_wrapper_attributes([ 'class' => 'sz-speakers-wrap' ]) and remove the hard-coded class attribute.

Suggested change
class="sz-speakers-wrap"
data-speaker-config="<?php echo esc_attr( wp_json_encode( $speaker_config ) ); ?>"
<?php echo get_block_wrapper_attributes(); ?>
data-speaker-config="<?php echo esc_attr( wp_json_encode( $speaker_config ) ); ?>"
<?php echo get_block_wrapper_attributes( array( 'class' => 'sz-speakers-wrap' ) ); ?>

Copilot uses AI. Check for mistakes.
…ptions

- Changed the data fetching URLs in render.php to use 'apiCode' instead of 'publicSlug'.
- Added a new TextControl for 'Sessionize API Code' in edit.js to allow users to input the API code.
- Updated the instructions in the Placeholder to reflect the use of API code.
- Modified view.js to use 'sessionizeApiCode' for local storage key and adjusted the sessionize public site link generation.
- Enhanced date formatting options to include 'Year/Month/Day' format in both display and filtering functions.

Signed-off-by: Chris Abraham <cjyabraham@gmail.com>
Signed-off-by: Chris Abraham <cjyabraham@gmail.com>
Signed-off-by: Chris Abraham <cjyabraham@gmail.com>
Copilot AI review requested due to automatic review settings April 19, 2026 19:15
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 28 out of 31 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +89 to +92
<div
class="sched-wrapper sched"
data-sched-config="<?php echo esc_attr( wp_json_encode( $sched_config ) ); ?>"
<?php echo get_block_wrapper_attributes(); ?>
Copy link

Copilot AI Apr 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This <div> renders a class attribute and also prints get_block_wrapper_attributes(), which typically includes its own class="...". That produces duplicate class attributes (invalid HTML) and may break styling/JS targeting. Prefer echo get_block_wrapper_attributes( array( 'class' => 'sched-wrapper sched' ) ); and remove the hard-coded class attribute.

Suggested change
<div
class="sched-wrapper sched"
data-sched-config="<?php echo esc_attr( wp_json_encode( $sched_config ) ); ?>"
<?php echo get_block_wrapper_attributes(); ?>
<div
data-sched-config="<?php echo esc_attr( wp_json_encode( $sched_config ) ); ?>"
<?php echo get_block_wrapper_attributes( array( 'class' => 'sched-wrapper sched' ) ); ?>

Copilot uses AI. Check for mistakes.
Comment on lines +792 to +801
function warmSpeakerAssets_( speakers ) {
const seen = new Set();
( speakers || [] ).forEach( ( s ) => {
const avatar = String( s?.profilePicture || '' ).trim();
if ( ! avatar || seen.has( avatar ) ) {
return;
}
seen.add( avatar );
preloadImage_( avatar );
} );
Copy link

Copilot AI Apr 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warmSpeakerAssets_ preloads every speaker avatar by creating new Image() instances. For large events this can trigger hundreds/thousands of network requests and significantly impact page performance/bandwidth. Consider limiting warming to above-the-fold/visible cards, adding a hard cap, or disabling this by default (or gating behind a config option).

Copilot uses AI. Check for mistakes.
Comment on lines +24 to +30
function sessionize_register_blocks() {
$blocks_dir = __DIR__ . '/blocks';

register_block_type( $blocks_dir . '/sessionize-schedule' );
register_block_type( $blocks_dir . '/sessionize-speakers' );
}
add_action( 'init', 'sessionize_register_blocks' );
Copy link

Copilot AI Apr 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The init function name sessionize_register_blocks is very generic and could collide with functions from other plugins/themes. Other plugins in this repo use a more specific prefix (e.g. cgb_block_*). Consider renaming to something plugin-scoped like sessionize_blocks_register_blocks and updating the add_action accordingly.

Suggested change
function sessionize_register_blocks() {
$blocks_dir = __DIR__ . '/blocks';
register_block_type( $blocks_dir . '/sessionize-schedule' );
register_block_type( $blocks_dir . '/sessionize-speakers' );
}
add_action( 'init', 'sessionize_register_blocks' );
function sessionize_blocks_register_blocks() {
$blocks_dir = __DIR__ . '/blocks';
register_block_type( $blocks_dir . '/sessionize-schedule' );
register_block_type( $blocks_dir . '/sessionize-speakers' );
}
add_action( 'init', 'sessionize_blocks_register_blocks' );

Copilot uses AI. Check for mistakes.
Signed-off-by: Chris Abraham <cjyabraham@gmail.com>
… slashes

Signed-off-by: Chris Abraham <cjyabraham@gmail.com>
Copilot AI review requested due to automatic review settings April 20, 2026 12:06
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 28 out of 31 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +29 to +32
$speaker_config = array(
'sessionizeAllDataUrl' => 'https://sessionize.com/api/v2/' . esc_attr( $attributes['apiCode'] ) . '/view/All',
'scheduleBaseUrl' => esc_url( $attributes['scheduleBaseUrl'] ),

Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The config values are being escaped (esc_attr, esc_url) before being JSON-encoded and placed into a data-* attribute. This can double-escape values (e.g. & becoming &#038;) and break URLs/strings when parsed by JS. Prefer sanitizing (e.g. sanitize_text_field / esc_url_raw) when building the config array, and only escaping once at output time with esc_attr( wp_json_encode(...) ).

Copilot uses AI. Check for mistakes.
Comment on lines +1152 to +1153
document.documentElement.style.setProperty( '--sz-purple', theme );
document.documentElement.style.setProperty( '--sz-purple-2', theme );
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block sets --sz-* CSS variables on document.documentElement, which affects the entire page and can cause conflicts if multiple Sessionize blocks are present or if other components reuse similar variables. Consider scoping these variables to the block root (and to the moved modal element) instead of the global <html> element.

Suggested change
document.documentElement.style.setProperty( '--sz-purple', theme );
document.documentElement.style.setProperty( '--sz-purple-2', theme );
root.style.setProperty( '--sz-purple', theme );
root.style.setProperty( '--sz-purple-2', theme );

Copilot uses AI. Check for mistakes.
Comment on lines +5 to +17
:root {
--sz-purple: #7a1f52;
--sz-purple-2: #8b2a62;
--sz-card: #ffffff;
--sz-text: #121212;
--sz-muted: #4b4b4b;
--sz-radius: 18px;
--sz-card-radius: 14px;
--sz-modal-top-offset: 18px;
--sz-vvh: 100vh;
--sz-vvtop: 0px;
--sz-mobile-h: 100dvh;
}
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CSS custom properties are defined on :root, so they apply globally across the site and can unintentionally affect other blocks/pages (and be affected by other CSS). Prefer scoping these variables to .sz-speakers-wrap (or another block-specific root) and rely on cascading for the modal by setting the same vars on the modal/root when opened.

Copilot uses AI. Check for mistakes.
Comment on lines +1114 to +1122
document.addEventListener( 'keydown', ( e ) => {
if ( modal.getAttribute( 'aria-hidden' ) === 'true' ) {
return;
}
if ( e.key === 'Escape' ) {
e.preventDefault();
closeModal_();
}
} );
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wireModalControls_ adds a document-level keydown listener every time the block initializes. If multiple speaker blocks are on the page, Escape handling will be registered multiple times and all handlers will run. Consider registering a single shared listener (or namespacing/removing listeners on teardown) and scoping it so only the active modal instance handles Escape.

Copilot uses AI. Check for mistakes.
Comment on lines +50 to +57
'sessionizeAllDataUrl' => 'https://sessionize.com/api/v2/' . esc_attr( $attributes['apiCode'] ) . '/view/All',
'sessionizeGridDataUrl' => 'https://sessionize.com/api/v2/' . esc_attr( $attributes['apiCode'] ) . '/view/GridSmart',
'sessionizeApiCode' => esc_attr( $attributes['apiCode'] ),
'sessionizePublicSlug' => esc_attr( $attributes['publicSlug'] ),

'primaryFilterTitle' => esc_attr( $attributes['primaryFilterTitle'] ),
'timeFormat' => esc_attr( $attributes['timeFormat'] ),
'dateFormat' => esc_attr( $attributes['dateFormat'] ),
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like the speakers block, the schedule config values are escaped with esc_attr(...) before JSON encoding. That can double-escape/alter values (notably publicSlug, filter titles, etc.) when the JS reads them. Prefer sanitizing raw values for storage in the config array and escaping only once at output time.

Suggested change
'sessionizeAllDataUrl' => 'https://sessionize.com/api/v2/' . esc_attr( $attributes['apiCode'] ) . '/view/All',
'sessionizeGridDataUrl' => 'https://sessionize.com/api/v2/' . esc_attr( $attributes['apiCode'] ) . '/view/GridSmart',
'sessionizeApiCode' => esc_attr( $attributes['apiCode'] ),
'sessionizePublicSlug' => esc_attr( $attributes['publicSlug'] ),
'primaryFilterTitle' => esc_attr( $attributes['primaryFilterTitle'] ),
'timeFormat' => esc_attr( $attributes['timeFormat'] ),
'dateFormat' => esc_attr( $attributes['dateFormat'] ),
'sessionizeAllDataUrl' => 'https://sessionize.com/api/v2/' . sanitize_text_field( $attributes['apiCode'] ) . '/view/All',
'sessionizeGridDataUrl' => 'https://sessionize.com/api/v2/' . sanitize_text_field( $attributes['apiCode'] ) . '/view/GridSmart',
'sessionizeApiCode' => sanitize_text_field( $attributes['apiCode'] ),
'sessionizePublicSlug' => sanitize_text_field( $attributes['publicSlug'] ),
'primaryFilterTitle' => sanitize_text_field( $attributes['primaryFilterTitle'] ),
'timeFormat' => sanitize_text_field( $attributes['timeFormat'] ),
'dateFormat' => sanitize_text_field( $attributes['dateFormat'] ),

Copilot uses AI. Check for mistakes.
Comment on lines +744 to +749
const a = document.createElement( 'a' );
a.className = 'sz-modal__link';
a.href = String( link.url || '' ).trim();
a.target = '_blank';
a.rel = 'noopener';
a.setAttribute( 'aria-label', label );
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

link.url from the Sessionize API is assigned directly to a.href. If the API data contains a javascript: (or other unsafe) URL, this becomes an XSS vector when clicked. Validate/normalize URLs before assigning (e.g., allow only http/https/mailto, otherwise skip the link), and consider using rel="noopener noreferrer" for external links opened with _blank.

Copilot uses AI. Check for mistakes.
Signed-off-by: Chris Abraham <cjyabraham@gmail.com>
Signed-off-by: Chris Abraham <cjyabraham@gmail.com>
Copilot AI review requested due to automatic review settings April 20, 2026 16:52
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 28 out of 31 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Signed-off-by: Chris Abraham <cjyabraham@gmail.com>
…er responsiveness

- Changed modal height and max-height from var(--sz-vvh) to 100dvh in style-index.css and style.css
- Ensured consistent modal sizing across different screen sizes and orientations

Signed-off-by: Chris Abraham <cjyabraham@gmail.com>
Copilot AI review requested due to automatic review settings April 20, 2026 18:29
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 28 out of 31 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Signed-off-by: Chris Abraham <cjyabraham@gmail.com>
@cjyabraham cjyabraham marked this pull request as ready for review April 20, 2026 20:38
Copilot AI review requested due to automatic review settings April 20, 2026 20:38
@cjyabraham cjyabraham merged commit eda2efe into main Apr 20, 2026
10 of 11 checks passed
@cjyabraham cjyabraham deleted the sessionize branch April 20, 2026 20:39
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 27 out of 30 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1144 to +1145
document.documentElement.style.setProperty( '--sz-purple', theme );
document.documentElement.style.setProperty( '--sz-purple-2', theme );
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block sets CSS variables on document.documentElement (--sz-purple, --sz-purple-2), which makes the styling global. If multiple speaker blocks with different themes are on the same page, the last-initialized block will override the variables for all blocks. Consider scoping these variables to the block root element (e.g., root.style.setProperty(...)) and updating the CSS to read vars from .sz-speakers-wrap rather than :root.

Suggested change
document.documentElement.style.setProperty( '--sz-purple', theme );
document.documentElement.style.setProperty( '--sz-purple-2', theme );
root.style.setProperty( '--sz-purple', theme );
root.style.setProperty( '--sz-purple-2', theme );

Copilot uses AI. Check for mistakes.
Comment on lines +736 to +743
const a = document.createElement( 'a' );
a.className = 'sz-modal__link';
a.href = String( link.url || '' ).trim();
a.target = '_blank';
a.rel = 'noopener';
a.setAttribute( 'aria-label', label );
a.title = label;
a.innerHTML = '<span class="sz-modal__linkicon" aria-hidden="true">' + icon + '</span>';
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The speaker social link href is set directly from Sessionize data. If a link URL is javascript:/data: (or otherwise malformed), clicking it becomes an XSS/vector. Validate/normalize the URL and only allow safe protocols (e.g., http:/https:) before assigning to a.href. Also consider using rel="noopener noreferrer" when target="_blank".

Copilot uses AI. Check for mistakes.
"attributes": {
"apiCode": {
"type": "string",
"default": "pc6leesj"
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default apiCode causes the block to immediately fetch data from a specific external Sessionize event (pc6leesj) even if the editor hasn't configured anything. For production, it’s safer to default this to an empty string and show an editor-side placeholder instead, to avoid unintended external requests/content.

Suggested change
"default": "pc6leesj"
"default": ""

Copilot uses AI. Check for mistakes.
"attributes": {
"apiCode": {
"type": "string",
"default": "pc6leesj"
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default apiCode is set to pc6leesj, which will trigger external Sessionize fetches by default and may surface unrelated content if someone inserts the block without configuring it. Consider defaulting apiCode to an empty string and requiring explicit configuration to avoid unintended external dependencies/requests.

Suggested change
"default": "pc6leesj"
"default": ""

Copilot uses AI. Check for mistakes.
Comment on lines +864 to +878
function sessionUrl_( sessionId ) {
const base = String( SPEAKER_CONFIG.scheduleBaseUrl || '' ).trim();
if ( ! base ) {
return '#';
}
const normalizedBase = base.replace( /\/?$/, '/' );
try {
const url = new URL( normalizedBase );
url.search = '';
url.searchParams.set( 'id', String( sessionId || '' ).trim() );
return url.toString();
} catch ( _ ) {
return '#';
}
}
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The editor help text says leaving scheduleBaseUrl blank disables session links, but sessionUrl_() returns '#' when the base URL is empty/invalid. This still renders clickable <a href="#"> links that will jump the page to the top. Consider returning an empty string/null and conditionally rendering a non-link title when links are disabled.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants